package de.openkanban.client.ui.presenter;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestBuilder.Method;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.smartgwt.client.util.SC;

/**
 * Powerful class that provides creation of HTTP requests by using
 * RequestParameterMaps that are created by the DTOs.
 * Uses the GWT RequestBuilder for sending the requests.
 */
public class PreparedRequest {

	private Method requestMethod = RequestBuilder.POST;

	private String[] contentHeader = { "Content-Type", "application/x-www-form-urlencoded" };

	private String servletName = "service";

	private String contextName = null;

	private String ressourceName = null;

	private Map<String, String> requestParameters = new HashMap<String, String>();

	private PreparedRequest(String contextName, String ressourceName) {
		this.contextName = contextName;
		this.ressourceName = ressourceName;
	}

	/**
	 * Fills the internal parameterMap with HTTP Parameters.
	 * @param contextName
	 * @param ressourceName
	 * @param params
	 */
	public PreparedRequest(String contextName, String ressourceName, String... params) {
		this(contextName, ressourceName);

		if (params != null) {
			for (int i = 0; i < params.length; i += 2) {
				requestParameters.put(params[i], params[i + 1]);
			}
		}
	}

	/**
	 * Fills the internal parameterMap with HTTP Parameters.
	 * @param contextName
	 * @param ressourceName
	 * @param param
	 */
	public <T extends RequestParameterMap> PreparedRequest(String contextName, String ressourceName, T param) {
		this(contextName, ressourceName);
		requestParameters.putAll(param.valuesToMap());
	}

	/**
	 * Sends the prepared Request, which is configured through the
	 * constructor parameters
	 * @param requestCallback
	 */
	public void sendAsyncRequest(RequestCallback requestCallback) {
		RequestBuilder builder = new RequestBuilder(requestMethod, servletName + "/" + contextName + "/" + ressourceName);
		builder.setHeader(contentHeader[0], contentHeader[1]);

		try {
			String preparedRequestString = getRequestDataString();
			builder.sendRequest(preparedRequestString, requestCallback);
		} catch (RequestException e) {
			SC.say("Failed to send the request: " + e.getMessage());
		}
	}

	private String getRequestDataString() {
		String result = "";

		Set<String> keys = requestParameters.keySet();
		for (String key : keys) {
			if (key != null) {
				String value = requestParameters.get(key);
				result += "&" + key + "=" + value;
			}
		}

		return result.replaceFirst("&", "");
	}

}
